package snooker.scoreboard.persistence;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;

import snooker.scoreboard.Match;
import snooker.scoreboard.frame.Frame;
import snooker.scoreboard.frame.Score;
import android.os.Environment;
import android.util.Log;

public class FileHandler {
	private static final String LOG_TAG 		= "FILE HANDLER";
	private static final String ROOT_FOLDER 	= "/snooker_results";
	public static final String HEADER		 	= "Player,Frame,Type,Break,Ball,Points,Time,wasLucky";
	public static final String OLD_HEADER  		= "Player,Frame,Type,Break,Ball,Points,Time";
	public static final int FILE_FORMAT_VERSION_1 = 1;
	public static final int FILE_FORMAT_VERSION_2 = 2;
	public static final int FILE_FORMAT_VERSION_3 = 3;
	
	public static boolean saveMatch() throws SnookerFileException {
		Match match = Match.getCurrentMatch();
		
		boolean result = false;
		try {
			File root = Environment.getExternalStorageDirectory();
			Log.i(LOG_TAG, "root=" + root);
			if (root.canWrite()){
				String rootFolderPath = root + ROOT_FOLDER;
				Log.i(LOG_TAG, "rootFolderPath=" + rootFolderPath);
				File rootFolder = new File(rootFolderPath);
				if (!rootFolder.isDirectory()) {
					Log.i(LOG_TAG, "Does not exists " + rootFolderPath);
					result = rootFolder.mkdir();
					Log.i(LOG_TAG, "Create result=" + result);
				}
				String name = match.getFileName();
				File gpxfile = new File(rootFolderPath, name);
				FileWriter gpxwriter = new FileWriter(gpxfile);
				BufferedWriter out = new BufferedWriter(gpxwriter);
				out.write(HEADER);
				out.write("\n");
				for (Frame f: match.getFrames()) {
					Log.i(LOG_TAG, "Saving frame: " + f.getFrameId());
					Log.i(LOG_TAG, "Saving history size: " + f.getScoreHistory().getScoreList().size());
					for (Score state: f.getScoreHistory().getScoreList()) {
						String playerName = state.getPlayerId() == Match.PLAYER1 ? 
								match.getPlayer1Name() : 
									match.getPlayer2Name();
					    
						Log.i(LOG_TAG, "Saving state: " + state.toString());
						out.write(state.getSerializedStringOld(playerName) + "\n");
					}
				}
				out.close();
				result = true;
				//saveMatchStatistics(match);
			} else {
				 Log.e(LOG_TAG, "Could not save file to " + root);
				 throw new SnookerFileException(SnookerFileException.SNOOKER_CANT_SAVE); 
			}
		} catch (IOException e) {
			e.printStackTrace();
			Log.e(LOG_TAG, "Could not write file root folder does not exists");
			throw new SnookerFileException(SnookerFileException.SNOOKER_CANT_SAVE); 
		}
		return result;
	}
	
	public static void loadMatch(String fileName) throws SnookerFileException {
		try {
//			int fileFormatVersion = 0;
			File root = Environment.getExternalStorageDirectory();
			Log.i(LOG_TAG, "root=" + root);
			if (root.canRead()){
				String rootFolderPath = root + ROOT_FOLDER;
				Log.i(LOG_TAG, "rootFolderPath=" + rootFolderPath);
				File rootFolder = new File(rootFolderPath);
				if (!rootFolder.exists()) {
					Log.i(LOG_TAG, "Does not exists " + rootFolderPath);
					throw new SnookerFileException(SnookerFileException.SNOOKER_FILE_NOT_ACCESSABLE);
				}
				File gpxfile = new File(rootFolderPath, fileName);
				if (!gpxfile.exists()) {
					Log.i(LOG_TAG, "Does not exists " + fileName);
					throw new SnookerFileException(SnookerFileException.SNOOKER_FILE_NOT_EXISTS);
				}
				if (!gpxfile.canRead()) {
					Log.i(LOG_TAG, "Can not read file " + fileName);
					throw new SnookerFileException(SnookerFileException.SNOOKER_FILE_NOT_READABLE);
				}
				FileReader gpxreader = new FileReader(gpxfile);
				BufferedReader in = new BufferedReader(gpxreader);
				String line = in.readLine();
				ILineParser lineParser = new LineParser(fileName);
				lineParser.preProcessing(line);
				while ((line = in.readLine()) != null) {
					lineParser.processLine(line);
				}
				in.close();
				lineParser.postProcessing();
			}
		} catch (IOException e) {
			e.printStackTrace();
			Log.e(LOG_TAG, "Could not write file " + e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new SnookerFileException(SnookerFileException.SNOOKER_FILE_FORMAT_ERROR, e.getMessage());
		}
	}
	
//	private static final String T = ",";
//	private static final String NL = "\r\n";
//	private static boolean saveMatchStatistics(Match match) throws SnookerFileException {
//		boolean result = false;
//		try {
//			File root = Environment.getExternalStorageDirectory();
//			Log.i(LOG_TAG, "root=" + root);
//			if (root.canWrite()){
//				String rootFolderPath = root + ROOT_FOLDER;
//				Log.i(LOG_TAG, "rootFolderPath=" + rootFolderPath);
//				File rootFolder = new File(rootFolderPath);
//				if (!rootFolder.isDirectory()) {
//					Log.i(LOG_TAG, "Does not exists " + rootFolderPath);
//					result = rootFolder.mkdir();
//					Log.i(LOG_TAG, "Create result=" + result);
//				}
//				String name = match.getFileName().replaceAll("match", "match_stat");
//				File gpxfile = new File(rootFolderPath, name);
//				FileWriter gpxwriter = new FileWriter(gpxfile);
//				BufferedWriter out = new BufferedWriter(gpxwriter);
//				List<StatisticRecord> srl = Statistics.getMatchStatistics(match);
//				for (StatisticRecord sr: srl) {
//						out.write(sr.getName() + T + sr.getValue1() + T + 
//								sr.getValue2() + NL);
//				}
//				boolean isfirstrow = true;
//				for (Frame frame: match.getFrames()) {
//					List<StatisticRecord> lsr = Statistics.getFrameStatistics(
//							Match.getCurrentMatch(), frame.getFrameId());
//					Log.i(LOG_TAG, "frameid=" + frame.getFrameId());
//					if (lsr == null) {
//						continue;
//					}
//					if (isfirstrow) {
//						isfirstrow = false;
//						out.write(NL);
//						for (StatisticRecord sr: lsr) {
//							out.write(sr.getName() + T);
//						}
//					}
//					out.write(NL + "Frame " + frame.getFrameId() + "." + NL);
//					for (StatisticRecord sr: lsr) {
//						out.write(sr.getValue1() + T);
//					}
//					out.write(NL);
//					for (StatisticRecord sr: lsr) {
//						out.write(sr.getValue2() + T);
//					}
//				}
//				out.close();
//				result = true;
//			} else {
//				 Log.e(LOG_TAG, "Could not save file to " + root);
//				 throw new SnookerFileException(SnookerFileException.SNOOKER_CANT_SAVE); 
//			}
//		} catch (IOException e) {
//			e.printStackTrace();
//			Log.e(LOG_TAG, "Could not write file root folder does not exists");
//			throw new SnookerFileException(SnookerFileException.SNOOKER_CANT_SAVE); 
//		}
//		return result;
//	}
	
	public static String[] getFileNames() throws SnookerFileException {
		String[] fileList = new String[0];
		try {
			File root = Environment.getExternalStorageDirectory();
			Log.i(LOG_TAG, "root=" + root);
			if (root.canRead()){
				String rootFolderPath = root + ROOT_FOLDER;
				File folder = new File(rootFolderPath);
				Log.i(LOG_TAG, "root=" + rootFolderPath);
				if (folder.exists() && folder.canRead()) {
					Log.i(LOG_TAG, "root=" + rootFolderPath);
					FilenameFilter filter = new FilenameFilter() { 
						public boolean accept(File dir, String name) { 
							return name.endsWith(".csv") && !name.contains("match_stat"); 
						} 
					}; 
					fileList = folder.list(filter);
					if (fileList == null) {
						fileList = new String[0];
					}
				} else {
					throw new SnookerFileException(SnookerFileException.SNOOKER_FILE_NOT_ACCESSABLE);
				}
			} else {
				throw new SnookerFileException(SnookerFileException.SNOOKER_FILE_NOT_ACCESSABLE);
			}
		} catch (Exception e) {
			e.printStackTrace();
			Log.e(LOG_TAG, "Could not write file root folder does not exists");
			throw new SnookerFileException(SnookerFileException.SNOOKER_FILE_NOT_ACCESSABLE);
		}
		return fileList;
	}
	
}
